package com.yunqiao.api.controller;


import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpUtil;
import cn.hutool.log.Log;
import cn.hutool.log.LogFactory;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.alibaba.fastjson.parser.Feature;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.CertAlipayRequest;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.internal.util.AlipayEncrypt;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipaySystemOauthTokenRequest;
import com.alipay.api.response.AlipaySystemOauthTokenResponse;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.yunqiao.api.config.WxPayProperties;
import com.yunqiao.api.utils.JwtUtils;
import com.yunqiao.common.pay.AliPay;
import com.yunqiao.common.utils.ACE;
import com.yunqiao.common.utils.R;
import com.yunqiao.common.validator.ValidatorUtils;
import com.yunqiao.service.api.UserService;
import com.yunqiao.service.api.entity.UserEntity;
import com.yunqiao.service.api.form.AliLoginForm;
import com.yunqiao.service.api.form.Login;
import com.yunqiao.service.api.form.WxLoginForm;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * 微信授权登录
 */
@RestController
@RequestMapping("/api/")
@Api(tags = "AppAccountController", description = "APP登陆注册板块")
public class WxLoginController {
    private static final Log log = LogFactory.get();
    @Resource
    private UserService userService;
    @Resource
    private JwtUtils jwtUtils;
    @Resource
    private WxPayProperties properties;
    @PostMapping("wx/login")
    @ApiOperation("微信小程序授权登录")
    public R login(@RequestBody WxLoginForm form){

        try {
            //表单校验
            ValidatorUtils.validateEntity(form);
            Map<String,Object> params= new HashMap<>();
            params.put("appid",properties.getUserAppid());
            params.put("secret",properties.getUserAppSecret());
            params.put("js_code",form.getCode());
            params.put("grant_type","authorization_code");
            Map<String, Object> map = new HashMap<>();
            JSONObject jsonObject= JSON.parseObject(HttpUtil.get("https://api.weixin.qq.com/sns/jscode2session",params));
            if(jsonObject.getIntValue("errcode")==0){
                Login loginForm=new Login();
                loginForm.setOpenId(jsonObject.getString("openid"));
                UserEntity userEntity = userService.Wxlogin(loginForm);
                if(userEntity==null){
                    JSONObject json= ACE.wxDecrypt(form.getEncrypted(),jsonObject.getString("session_key"),form.getIv());
                    userEntity=new UserEntity();
                    userEntity.setWxCloudOpenid(loginForm.getOpenId());
                    userEntity.setRoleType(1);
                    if(json!=null){
                        try {
                            userEntity.setSex(json.getInteger("gender"));
                            userEntity.setAvatar(json.getString("avatarUrl"));
                            userEntity.setCreateTime(new Date());
                            userEntity.setCity(json.getString("city"));
                            userEntity.setProvince(json.getString("province"));
                            userEntity.setName(json.getString("nickName"));
                        }catch (Exception e){
                            e.printStackTrace();
                        }
                    }
                    userEntity.setDeleted(0);
                    return R.ok().put("userInfo",userEntity);
                    //userService.save(userEntity);
                }else if(userEntity!=null&&(userEntity.getAvatar()==null||userEntity.getAvatar()==""||userEntity.getCity()==null||userEntity.getProvince()==null)){
                    JSONObject json= ACE.wxDecrypt(form.getEncrypted(),jsonObject.getString("session_key"),form.getIv());
                    if(json!=null&&userEntity.getName()!=null){
                        try {
                            userEntity.setSex(json.getInteger("gender"));
                            userEntity.setAvatar(json.getString("avatarUrl"));
                            userEntity.setCreateTime(new Date());
                            userEntity.setCity(json.getString("city"));
                            userEntity.setProvince(json.getString("province"));
                            userEntity.setName(json.getString("nickName"));
                        }catch (Exception e){
                            e.printStackTrace();
                        }
                        userService.updateById(userEntity);
                    }
                }
                //生成token
                String token = jwtUtils.generateToken(form.getType(),userEntity.getId());
                map.put("token", token);
                map.put("expire", jwtUtils.getExpire());
                map.put("userId", userEntity.getId());
                map.put("name", userEntity.getName());
                map.put("isSetDetails", StrUtil.isNotBlank(userEntity.getName()));
                if(userEntity.getPhone()!=null&&userEntity.getPhone().trim()!=""){
                    map.put("phone",userEntity.getPhone());
                }
                return R.ok(map);
            }else if(jsonObject.getIntValue("errcode")==-1){
                return R.error(jsonObject.getString("errmsg"));

            }else  if(jsonObject.getIntValue("errcode")==40029){
                return R.error(jsonObject.getString("errmsg"));

            }else if(jsonObject.getIntValue("errcode")==45011){
                return R.error(jsonObject.getString("errmsg"));
            }
        }catch (Exception e){
            log.error("登录授权出现错误{}",e.getMessage());
        }


        //用户登录

        return R.error("未知错误请联系管理员");
    }

    /**
     * 支付宝小程序授权登录
     * @param form
     * @return
     */
    @PostMapping("ali/login")
    public R aliLogin(@RequestBody AliLoginForm form){
        AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do",AliPay.ALI_XCX_ID_user,AliPay.ALI_XCX_PUBLIC_KEY_user,"json","GBK",AliPay.ALI_PAY_PUBLIC_KEY_user,"RSA2");
        try {
            AlipaySystemOauthTokenRequest request = new AlipaySystemOauthTokenRequest();
            request.setGrantType("authorization_code");
            request.setCode(form.getCode());
            AlipaySystemOauthTokenResponse response = alipayClient.execute(request);
            if(response.isSuccess()){
                response.getUserId();
                UserEntity userEntity=userService.getOne(new QueryWrapper<UserEntity>().eq("ali_cloud_openid",response.getUserId()).eq("role_type",1));
                if(userEntity!=null){
                    //生成token
                    String token = jwtUtils.generateToken(form.getType(),userEntity.getId());
                    Map<String,Object> map=new HashMap<>();
                    map.put("token", token);
                    map.put("expire", jwtUtils.getExpire());
                    map.put("userId", userEntity.getId());
                    map.put("name", userEntity.getName());
                    map.put("isSetDetails", StrUtil.isNotBlank(userEntity.getName()));
                    map.put("phone",userEntity.getPhone());
                    map.put("aliCloudOpenid",response.getUserId());
                    return R.ok(map);
                }
                return R.ok().put("aliCloudOpenid",response.getUserId());
            }else{
                return R.error().put("msg","网络出现异常,请退出后重试");
            }
        } catch (AlipayApiException e) {
            e.printStackTrace();
            return R.error().put("msg","网络出现异常,请退出后重试");
        }


    }

    /**
     * 解密手机号
     * @param form
     * @return
     */
    @PostMapping("ali/getPhone")
    public R getPhoneNumber(@RequestBody AliLoginForm form){
        String response=form.getResponse();
        //1. 获取验签和解密所需要的参数
        Map<String, String> openapiResult = JSON.parseObject(response,
                new TypeReference<Map<String, String>>() {
                }, Feature.OrderedField);
        String signType = StringUtils.defaultIfBlank(openapiResult.get("signType"), "RSA2");
        String charset = StringUtils.defaultIfBlank(openapiResult.get("charset"), "UTF-8");
        String encryptType = StringUtils.defaultIfBlank(openapiResult.get("encryptType"), "AES");
        String sign = openapiResult.get("sign");
        String content = openapiResult.get("response");
        //2. 验签
        String signContent =  "\"" + content + "\"";
        String signVeriKey = AliPay.ALI_XCX_ID_user;
        String decryptKey ="Xl8/zaYu+rL8E/KhxfRh7Q==";
        boolean signCheckPass = false;
        try {
            signCheckPass = AlipaySignature.rsaCheck(signContent, sign, signVeriKey, charset, signType);
        } catch (AlipayApiException e) {
            //验签异常, 日志
        }
        if(!signCheckPass) {
            //验签不通过（异常或者报文被篡改），终止流程（不需要做解密）
            return R.error().put("msg","签名失败");
        }

        //3. 解密
            try {
                String phone=AlipayEncrypt.decryptContent(content, encryptType, decryptKey, charset);
                UserEntity user=userService.findByPhoneOrOpendId(phone,null);
                if(user!=null){
                    user.setAliCloudOpenid(form.getAliCloudOpenid());
                    userService.updateById(user);
                }else {
                    user=new UserEntity();
                    user.setPhone(phone);
                    user.setAliCloudOpenid(form.getAliCloudOpenid());
                    user.setName(form.getNickName());
                    user.setCity(form.getCity());
                    user.setProvince(form.getProvince());
                    user.setCreateTime(new Date());
                    user.setAvatar(user.getAvatar());
                    user.setRoleType(1);
                    user.setProvince(form.getProvince());
                    userService.save(user);

                }
                Map<String, Object> map = new HashMap<>();
                //生成token
                String token = jwtUtils.generateToken(form.getType(),user.getId());
                map.put("token", token);
                map.put("expire", jwtUtils.getExpire());
                map.put("userId", user.getId());
                map.put("name", user.getName());
                map.put("isSetDetails", StrUtil.isNotBlank(user.getName()));
                map.put("phone",user.getPhone());
                return R.ok(map);
            } catch (AlipayApiException e) {
                //解密异常, 记录日志
                return R.error().put("msg","解密失败");
            }
    }

}
